package com.skstudio.nuprint;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.text.format.Formatter;
import android.util.Log;

import com.skstudio.nuprint.lpd.LpdPrintJob;
import com.skstudio.nuprint.lpd.LpdQueue;
import com.skstudio.nuprint.lpd.LpdSerial;
import com.skstudio.nuprint.lpd.LpdWorkerThread;

public class LpdService extends IntentService implements LpdQueue.OnDocumentListener{

    public class PrintIOBinder extends Binder {
    	public LpdService getService() {
            return LpdService.this;
        }
    }
    
    private static String TAG = "PrbzPrt";
    
	public LpdService() {
		super(TAG);
		setIntentRedelivery(true);
	}

	private boolean mbKeepRun = true, mbExited = false;
	private PrintIOBinder mBinder = new PrintIOBinder();
	
	//public static final LpdSerial mSerial = new LpdSerial(new File("lpd_dump.bin"), false);
	public static final LpdSerial mSerial = null;
	ServerSocket mSrvSocket = null;
	
	@Override
	protected void onHandleIntent(Intent intent) {		
		Log.v(TAG, "onHandleIntent starts...");	

		WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		if (!wifi.isWifiEnabled()) return;
		WifiInfo wi = wifi.getConnectionInfo();
		if (wi == null) return;
		String ipAddress = Formatter.formatIpAddress(wi.getIpAddress());
		Log.v(TAG, ipAddress);
		
		File pubRoot = new File(Environment.getExternalStorageDirectory(), "pbprinter");
		if (!pubRoot.exists()) {
			pubRoot.mkdir();
		}
		
		try {
			mSrvSocket = new ServerSocket(5432);
			LpdQueue queue = LpdQueue.getInstance();
			queue.setListener(this);
			queue.start();
			
			while(mbKeepRun) {
				while (!LpdWorkerThread.canCreateNewThread()) {
					Thread.sleep(100);
				}
				Socket client = mSrvSocket.accept();
				LpdWorkerThread lpdWork = new LpdWorkerThread(client);
				lpdWork.start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		LpdQueue queue = LpdQueue.getInstance();
		queue.quit();
		closeSocket();
		
		mbExited = true;
		Log.v(TAG, "onHandleIntent exits");
	}

	protected void closeSocket() {
		if (mSrvSocket != null) {
			try {
				mSrvSocket.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}	
		mSrvSocket = null;
	}
	
	public static void writeCommand(byte[] command) {
		if (mSerial != null) {
			mSerial.writeCommand(command);
		}
	}
	
	@Override
	public IBinder onBind(Intent intent) {
		Log.v(TAG, "onBind");
		return mBinder;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		Log.v(TAG, "onStartCommand: flags " + flags + ", startId "+ startId);
		return super.onStartCommand(intent, flags, startId);
	}
	
	Notification mNotification = null;
	PendingIntent mPendingIntent = null;
	
	@Override
	public void onCreate()
	{
		Log.v(TAG, "onCreate");
		super.onCreate();
		
		Intent pdfListIntent = new Intent(this, MainActivity.class);
		mPendingIntent = PendingIntent.getActivity(this, 0, pdfListIntent, 0);
		
		mNotification = new Notification(R.drawable.icon_app_small, getText(R.string.app_name),
		        System.currentTimeMillis());
		mNotification.setLatestEventInfo(this, getText(R.string.app_run),
		        "Idle...", mPendingIntent);
		startForeground(Notification.FLAG_ONGOING_EVENT, mNotification);
	}
	
	@Override
	public void onDestroy()
	{
		Log.v(TAG, "onDestroy");
		mbKeepRun = false;
		closeSocket();
		
		while(!mbExited) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		super.onDestroy();
	}

	public void onNewDocument(LpdPrintJob job) {
		NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		mNotification.setLatestEventInfo(this, getText(R.string.app_run),
		        "New document(s) printed", mPendingIntent);
		nm.notify(Notification.FLAG_ONGOING_EVENT, mNotification);
	}

}
